package com.operation.job;

import com.operation.GlobalArgument;
import com.operation.address.LogicAddress;
import lombok.Data;

import java.util.*;

/**
 * 封装作业相关信息
 */
@Data
public class Job {
    private String name;
    private long start;
    private long end;//作业在外存中连续存储，分别为起始位置和结束位置
    private List<Long>address;//作业连续地址

    /**
     * 初始化作业构造方法
     * @param name 名称
     * @param start 开始位置
     * @param end 结束位置
     */
    public Job(String name, long start, long end) {
        this.name = name;
        this.start = start;
        this.end = end;
        this.address=new ArrayList<>();
        for(long i=start;i<=end;i++){
            this.address.add(i);
        }
    }

    /**
     * 模拟顺序执行
     * @return 逻辑地址引用串
     */
    public LogicAddress[]sequentialExecute(){

        int size= (int) (end-start+1);
        LogicAddress[] logicAddresses = new LogicAddress[size];
        for (long i = start; i <=end; i++) {
            logicAddresses[(int)(i-start)]=new LogicAddress(i, GlobalArgument.pageSize);
        }
        return logicAddresses;
    }

    /**
     * 模拟程序跳跃执行从一条指令直接跳到另外一条指令,同时需要确保第一个地址为start，最后一个地址为end
     * @return 逻辑地址引用串
     */
    public LogicAddress []skipExecution(){

        int size= (int) (end-start+1);
        LogicAddress[] logicAddresses = new LogicAddress[size];
        //打乱地址
        Collections.shuffle(this.address);
        //确保第一个地址为start，最后一个地址为end
        this.address.remove(start);
        this.address.remove(end);
        this.address.add(0,start);
        this.address.add(size-1,end);
        for (int i = 0; i < this.address.size(); i++) {
            logicAddresses[i]=new LogicAddress(address.get(i), GlobalArgument.pageSize);
        }
        return logicAddresses;
    }

    /**
     * 模拟实际程序执行,大部分连续，小部分跳跃
     * @return
     */
    public LogicAddress []actualExecution(int skip){

        int size= (int) (end-start+1);
        LogicAddress[] logicAddresses = new LogicAddress[size];
        Random random = new Random();
        for(int i=0;i<skip; i++){
            int shuffleStart = random.nextInt((int) (end - 2*GlobalArgument.pageSize));//作为打乱起点
            LinkedList<Long> temp = new LinkedList<>();
            for(int j=shuffleStart;j < shuffleStart+GlobalArgument.pageSize; j++){
                temp.add(address.remove(j));
            }
            Collections.shuffle(temp);
            address.addAll(temp);
        }
        //确保第一个地址为start，最后一个地址为end
        this.address.remove(start);
        this.address.remove(end);
        this.address.add(0,start);
        this.address.add(size-1,end);
        for (int i = 0; i < this.address.size(); i++) {
            logicAddresses[i]=new LogicAddress(address.get(i), GlobalArgument.pageSize);
        }
        return logicAddresses;
    }

    public LogicAddress []customExecution(){

        int size= GlobalArgument.pageReferenceNumber;
        LogicAddress[] logicAddresses = new LogicAddress[size];
        for (int i = 0; i < GlobalArgument.address.length; i++) {
            logicAddresses[i]=new LogicAddress(GlobalArgument.address[i], GlobalArgument.pageSize);
        }
        return logicAddresses;
    }
    //还可以定义其他执行方式


}
